<template>
    <template v-if="isList">
        <div class="video">   
        <tip :label="'视频列表'" />
        <div class="search">
            <SearchFrom :fromList="searchData" :btnList="btnData" @onClick="searchClick"></SearchFrom>
        </div>
        <BasicTable :tableData="tableInfo.tableData" :headerData="tableInfo.headerData" v-loading="loading">
            <template #title="{data}">
                <div style="display: flex; justify-content: center;align-items: center;height: 100%;">
                    <span v-if="!data.hideTitle">{{ data.title }}</span>
                    <el-icon  v-if="!data.hideTitle" color="#B57DF2" style="margin-left: 10px;cursor: pointer;" @click="data.hideTitle = true;inputTitleData = data.title "><EditPen /></el-icon>
                    <el-input
                        v-if="data.hideTitle"
                        class="tag-input"
                        size="small"
                        v-model="inputTitleData"
                        @keyup.enter="editTitleClick(data)"
                        @blur="editTitleClick(data)"
                    />
                </div>
            </template>
            <template #status="{data}">
            <div v-if="data.status == 'GENERATING'" style="display: flex;align-items: center;width: 100%;justify-content: center;">
                <a-spin size="small" style="margin-top:5px" />
                <span style="color: #FFF;margin-left: 10px;">生成中...</span>
            </div>
            <span v-else-if="data.status === 'FAILED'">
                失败
            </span>
              <span v-else>
                成功
              </span>
            </template>
            <template #tags="{data}">
              <div style="display: flex; align-items: center;">
                <div class="tag-box" >
                    <template v-if="data?.tags">
                    <el-tag  
                        style="margin-right: 6px; margin-bottom:4px;cursor: pointer;color: #B57DF2;border: 0;" 
                        :key="index"
                        :disable-transitions="true"
                        v-for="(item, index) in data?.tags?.split(',')" >
                        {{ item }}
                    </el-tag>
                    </template>
                </div>
                <el-icon color="#B57DF2" style="margin-left: 10px;;cursor: pointer;" @click="tagClick(data)"><EditPen /></el-icon>
              </div>
            </template>
            <template #avatarName="{data}">
                <div class="person-title">
                    <img :src="data.avatarCoverSmall" />
                    <span>{{ data.avatarName }}</span>
                </div>
            </template>
            <template #length="{data}">
                <span>{{ convertMinutesToHoursAndMinutes(data.length) }}</span>
            </template>
            <template #operate="{data}">
               <div class="operate" v-if="data.status !== 'GENERATING'">
                    <el-button style="width: 60px;margin-right: 14px;" color="#BC81FC" @click="catVideoClick(data.videoUrl, data.avatarCoverSmall)">查看视频</el-button>
                    <el-button style="width: 60px;" color="#BC81FC"  @click="downloadVideo(data.videoUrl, data.title)">下载视频</el-button>
               </div>
            </template>
        </BasicTable>
        <Pagination  :isShowTotal="true" :is-lable="true" :pageSize="pageSize"  :currentPage="currentPage"  :label="addBtn" @labelClick="createClick" :total="totalCount" @pageClick="pageClick"/> 
    </div>  
    <Dialog 
        :show="showDialog" 
        :title="dialogType == 'video'? '查看视频': '编辑标签'" 
        :width="dialogType == 'video'? 880: 0"
        :isCloseTip="false" 
        :is-custom-footer="false"
        @on-close="showDialog = false;videoUrl = ''"
        @on-sure-click="sureClick"
    >
        <template #content>
          <div v-if="dialogType == 'video'" style="margin: 0 auto;">
            <Video  :src="videoUrl"  :poster="previewUrl" />
          </div>
          <div class="tag-list" v-else>
             <el-tag
                    v-for="tag in tagListDialog"
                    :key="tag"
                    class="tag-item"
                    type="info" 
                    closable  
                    effect="plain" 
                    :disable-transitions="false"
                    @close="delTag(tag)"
                >
                {{ tag }}
            </el-tag>
            <el-input
                v-if="inputVisible"
                ref="InputRef"
                v-model="inputValue"
                class="tag-input"
                size="small"
                @keyup.enter="handleInputConfirm"
                @blur="handleInputConfirm"
            />
            <el-button v-else  size="small" @click="showInput">
                + 新建标签
            </el-button>
          </div>
        </template>
    </Dialog>
    </template>
    <router-view v-else></router-view>
   
</template>

<script setup lang="ts">
import tip from '@/components/tip/tip.vue';
import SearchFrom from '@/components/searchForm/searchForm.vue';
import BasicTable from '@/components/table/basicTable.vue'
import Pagination from '@/components/pagination/pagination.vue'
import Video from '@/components/video/video.vue'
import Dialog from '@/components/dialog/dialog.vue'
import { Plus, EditPen } from '@element-plus/icons-vue';
import {useRouter, onBeforeRouteUpdate} from 'vue-router'
import { storeToRefs } from 'pinia';
import {reactive,ref, onMounted, nextTick, onUnmounted} from 'vue';
import { useVideoStore } from '@/store/video';
import {FromInfo, BtnInfo} from '@/models/components/index'
import {getVideosList, getVideoListStatus, updateVideoInfo} from '@/service/video'
import { to } from 'await-to-js'
import {SearchData, TableInfo} from '@/models/home/video'
import {ElMessage, ElInput} from 'element-plus'
const route = useRouter();
const store = useVideoStore();
const { isList } = storeToRefs(store)
const tableInfo = reactive<TableInfo>({
  tableData: [],
  headerData: [
    {
        label: '视频编号',
        prop: 'id',
    },
    {
        label: '数字人',
        prop: 'avatarName',
        isCustom: true,
    },
    {
        label: '标题',
        prop: 'title',
        isCustom: true,
    },
    {
        label: '创建时间',
        prop: 'gmtCreate',
    },
    {
        label: '状态',
        prop: 'status',
        isCustom: true,
    },
    {
        label: '视频长度',
        prop: 'length',
        isCustom: true,
    },
    {
        label: '标签',
        prop: 'tags',
        isCustom: true,
        width: 120,
    },
    {
        label: '操作',
        prop: 'operate',
        isCustom: true,
        fixed: 'right'
    }
]
})
const totalCount = ref<number>(0)
const currentPage = ref<string | number>(1)
const pageSize = ref<string | number>(8)
const showDialog = ref<boolean>(false)
const loading = ref<boolean>(false)
const inputValue = ref('')
// const dynamicTags = ref(['Tag 1', 'Tag 2', 'Tag 3'])
const inputVisible = ref(false)
const InputRef = ref<InstanceType<typeof ElInput>>()
const tagListDialog = ref<string[]>([])
const dialogType = ref<string>('')
const videoUrl = ref<string>('')
const searchInfo = ref<any>({})
const searchData = reactive<FromInfo[]>([
        {label: '数字人', value: '', type: 'input', key: 'avatarName'},
        {label: '标题', value: '',type: 'input', key: 'title'},
        {label: '标签', value: '', type: 'input', key: 'tag'},
])
const previewUrl = ref<string>('')
const searchIds = ref<string[] | number[]>()
const timer = ref<any>(null)
const btnData = reactive<BtnInfo[]>([
        {color: '#542A80', label: '搜索'}
])
const editData = ref<any>(null);
const addBtn = {text: '创建视频', icon: Plus};
const inputTitleData = ref<string>();
onMounted( async () => {
  const search = {currentPage: currentPage.value, pageSize: pageSize.value}
  await getVideoListData(search)
})
onUnmounted(() => {
    clearInterval(timer.value)
})
onBeforeRouteUpdate(async (to) => {
    if(to.path == '/home/video') {
        const search = {currentPage: currentPage.value, pageSize: pageSize.value}
        await getVideoListData(search)
    }else {
        clearInterval(timer.value)
    }
   
})
const searchClick = async ({label, value}: any) => {
    searchInfo.value == value;
    searchData.forEach(val => {
        if (val.key)  {
         val.value = value[val.key]
        }
    })
    if(label == '搜索') {
        const search = {currentPage: currentPage.value, pageSize: pageSize.value}
        await getVideoListData({...search, ...value})
    }
}
const pageClick = async (e: string | number) => {
    currentPage.value = e;
    let searchInfo = searchData.reduce((acc, cur) => {
        if (cur.value && cur.key) {
            acc[cur.key] = cur.value;
        }
        return acc;
    }, {} as { [key: string]: any })
    await getVideoListData({currentPage: currentPage.value, pageSize: pageSize.value, ...searchInfo})
}
const getVideoListData = async (parms: SearchData): Promise<void> => {
   loading.value = true;
   const [err, data] = await to(getVideosList(parms))
   loading.value = false;
   if(err || !data.success) {
      ElMessage.error(`请求错误，${data.message}`)
      return;
   }
   tableInfo.tableData = data.items;
   searchIds.value = data.items.filter((res: any) => res.status === 'GENERATING').map((res:any) => res.id)
   clearInterval(timer.value)
   if(searchIds.value && searchIds.value?.length > 0) {
        timer.value = setInterval(async() => {
            searchIds.value && await getVideoStatusInfo(searchIds.value)
        }, 5000)
   }
   totalCount.value = data.totalCount;
}
const createClick = (e: string): void => {
    store.setIsList(false);
    route.push('/home/video/edit')
}
const catVideoClick = (url: string, img: string) => {
    dialogType.value = 'video'
    showDialog.value = true;
    videoUrl.value = url;
    previewUrl.value = img;
}
const tagClick = (data: any) => {
    dialogType.value = 'tag'
    showDialog.value = true;
    tagListDialog.value = data.tags && data.tags.split(',') || []
    editData.value = data;
}
const showInput = () => {
  inputVisible.value = true
  nextTick(() => {
    InputRef.value!.input!.focus()
  })
}
const delTag = (tag: string) => {
    tagListDialog.value.splice(tagListDialog.value.indexOf(tag), 1)
}
const sureClick = () => {
    if(dialogType.value == 'tag') {
      updateVideoInfoRes({id: editData.value.id, title: editData.value.title, tags: tagListDialog.value.join(','), updateField: 'tags'})
    }
    showDialog.value = false;
    videoUrl.value = '';
}
const editTitleClick = (item: any) => {
  item.hideTitle = false;
  if (inputTitleData.value !== item.title && inputTitleData.value) {
    updateVideoInfoRes({id: item.id, title: inputTitleData.value, tags: item.tag, updateField: 'title'})
  }
  inputTitleData.value = ''
}

const getVideoStatusInfo = async (data: string[] | number[]) => {
   const [err, res] = await to(getVideoListStatus({ids: data}))
   if(err || !res.success) {
    ElMessage.error(res.message)
    return;
   }
   
    let falseList: any[]  = [];
    let sucsList: any[] = []
   res.items.forEach((res: any) => {
        if(res.status == 'GENERATING') {
            falseList.push(res.id);
            return;
        }
        sucsList.push(res)
   })
   tableInfo.tableData.forEach((val: any) => {
        sucsList.forEach(res => {
            if(val.id == res.id) {
                val.status = res.status;
                val.length = res.length;
            }
        })
    })
    if(falseList.length <= 0 ) {
        clearInterval(timer.value)
    }
   searchIds.value = falseList;
}
const updateVideoInfoRes = async(data: any) => {
    const [err, res] = await to(updateVideoInfo(data))
    if(err || !res.success) {
        ElMessage.error(res.message)
        return
    }
    ElMessage.success("修改成功");
    await pageClick(currentPage.value);
}
const handleInputConfirm = () => {
  if (inputValue.value) {
    tagListDialog.value.push(inputValue.value)
  }
  inputVisible.value = false
  inputValue.value = ''
}
const downloadVideo = (url: string, name: string) => {
    fetch(url)
    .then(res => res.blob())
    .then(blob => {
        const a = document.createElement('a');
        const objectUrl = window.URL.createObjectURL(blob);
        a.href = objectUrl;
        a.download = name;
        a.click();
        window.URL.revokeObjectURL(objectUrl);
        a.remove();
    })
}
const convertMinutesToHoursAndMinutes = (seconds: number) => {
    if (isNaN(seconds) || seconds < 0) {
    return '请输入有效的秒数';
  }
  const hours = Math.floor(seconds / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  const remainingSeconds = seconds % 60;
  let formattedTime = '';
  if (hours > 0) {
    formattedTime += `${hours}小时`;
  }
  if (minutes > 0 || hours > 0) {
    formattedTime += `${minutes}分钟`;
  }
  formattedTime += `${remainingSeconds}秒`;
  return formattedTime;
}

</script>

<style lang="css" scoped>

.video {
    background: #25212B;
    height: 100%;
    border-radius: 10px;
    padding: 10px;
    box-sizing:border-box;
}
.search {
    margin-top: 20px;
}
.operate {
    display: flex;
    align-items: center;
    height: 100%;
    /* flex-direction: column; */
}
.operate :deep(.el-button+.el-button) {
    margin-left: 0;
}
.tag-box{
    display: flex; 
    flex-wrap: wrap; 
    width: 200px;
    height: 200px;
    justify-content: flex-start;
    background-color: #453C4F;
    padding: 4px 6px;
    border-radius: 10px;
    overflow: auto;
    max-height: 6vh;
}
.tag-list {
    display: flex;
    flex-wrap: wrap;
}
.tag-item {
    margin-right: 10px;
    /* margin-top: 10px; */
    color: #BC81FC;
}
.person-title {
    
}
.person-title > img {
    height: 50px;
    margin-right: 10px;
}
.tag-input {
    width: 100px;
}
:deep(.el-table__inner-wrapper) {
    max-height: 68vh;
    /* min-height: 62vh; */
}
:deep(:where(.css-dev-only-do-not-override-1qb1s0s).ant-spin .ant-spin-dot-item) {
    background-color: #BC81FC;
}
:deep(.operate >  .el-button) {
    /* background-color: #8252B3;
    border: 1px solid #8252B3;
    color: #292331; */
    /* margin-top: ; */
    font-size:  12px !important;
}

/* 整个滚动条 */
::-webkit-scrollbar {
  width: 4px; /* 设置滚动条的宽度 */
}

/* 滚动条轨道 */
::-webkit-scrollbar-track {
    display: none;
  background-color: #f1f1f1; /* 设置滚动条轨道的背景色 */
}

/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
  background-color: #DDDEE0; /* 设置滚动条滑块的颜色 */
  border-radius: 6px; /* 设置滚动条滑块的圆角 */
}

/* 当鼠标悬停在滚动条上时，滑块的样式 */
::-webkit-scrollbar-thumb:hover {
  background-color: #B2B2B2; /* 设置鼠标悬停时滚动条滑块的颜色 */
}

:deep(.el-loading-mask) {
    background: #51495F;
}
</style>